Add links to a generated SVG diagram.

Properly escape double quotes and backslashes in DOT while here.

Akinori MUSHA 11 anni fa
parent
commit
330486e79c
2 ha cambiato i file con 28 aggiunte e 14 eliminazioni
  1. 27 3
      app/helpers/application_helper.rb
  2. 1 11
      app/views/agents/diagram.html.erb

+ 27 - 3
app/helpers/application_helper.rb

@@ -15,18 +15,42 @@ module ApplicationHelper
15 15
     end
16 16
   end
17 17
 
18
-  def render_dot(dot_format_string)
18
+  def render_agents_diagram(agents)
19 19
     if (command = ENV['USE_GRAPHVIZ_DOT']) &&
20 20
        (svg = IO.popen([command, *%w[-Tsvg -q1 -o/dev/stdout /dev/stdin]], 'w+') { |dot|
21
-          dot.print dot_format_string
21
+          dot.print agents_dot(agents, true)
22 22
           dot.close_write
23 23
           dot.read
24 24
         } rescue false)
25 25
       svg.html_safe
26 26
     else
27 27
       tag('img', src: URI('https://chart.googleapis.com/chart').tap { |uri|
28
-            uri.query = URI.encode_www_form(cht: 'gv', chl: dot_format_string)
28
+            uri.query = URI.encode_www_form(cht: 'gv', chl: agents_dot(agents))
29 29
           })
30 30
     end
31 31
   end
32
+
33
+  private
34
+
35
+  def dot_id(string)
36
+    # Backslash escaping seems to work for the backslash itself,
37
+    # despite the DOT language document.
38
+    '"%s"' % string.gsub(/\\/, "\\\\\\\\").gsub(/"/, "\\\\\"")
39
+  end
40
+
41
+  def agents_dot(agents, rich = false)
42
+    "digraph foo {".tap { |dot|
43
+      agents.each.with_index do |agent, index|
44
+        if rich
45
+          dot << '%s[URL=%s];' % [dot_id(agent.name), dot_id(agent_path(agent.id))]
46
+        else
47
+          dot << '%s;' % dot_id(agent.name)
48
+        end
49
+        agent.receivers.each do |receiver|
50
+          dot << "%s->%s;" % [dot_id(agent.name), dot_id(receiver.name)]
51
+        end
52
+      end
53
+      dot << "}"
54
+    }
55
+  end
32 56
 end

+ 1 - 11
app/views/agents/diagram.html.erb

@@ -9,17 +9,7 @@
9 9
       </div>
10 10
 
11 11
       <div class='digraph'>
12
-        <%
13
-           dot_format_string = "digraph foo {"
14
-           @agents.each.with_index do |agent, index|
15
-             dot_format_string += "\"#{agent.name}\";"
16
-             agent.receivers.each do |receiver|
17
-               dot_format_string += "\"#{agent.name}\"->\"#{receiver.name}\";"
18
-             end
19
-           end
20
-           dot_format_string = dot_format_string + "}"
21
-        %>
22
-        <%= render_dot(dot_format_string) %>
12
+        <%= render_agents_diagram(@agents) %>
23 13
       </div>
24 14
     </div>
25 15
   </div>